out:
free_vmcs(vmcs);
+ if(v->arch.arch_vmx.io_bitmap_a != 0) {
+ free_xenheap_pages(v->arch.arch_vmx.io_bitmap_a, get_order(0x1000));
+ v->arch.arch_vmx.io_bitmap_a = 0;
+ }
+ if(v->arch.arch_vmx.io_bitmap_b != 0) {
+ free_xenheap_pages(v->arch.arch_vmx.io_bitmap_b, get_order(0x1000));
+ v->arch.arch_vmx.io_bitmap_b = 0;
+ }
v->arch.arch_vmx.vmcs = 0;
return error;
}
BUG_ON(v->arch.arch_vmx.vmcs == NULL);
free_vmcs(v->arch.arch_vmx.vmcs);
+ if(v->arch.arch_vmx.io_bitmap_a != 0) {
+ free_xenheap_pages(v->arch.arch_vmx.io_bitmap_a, get_order(0x1000));
+ v->arch.arch_vmx.io_bitmap_a = 0;
+ }
+ if(v->arch.arch_vmx.io_bitmap_b != 0) {
+ free_xenheap_pages(v->arch.arch_vmx.io_bitmap_b, get_order(0x1000));
+ v->arch.arch_vmx.io_bitmap_b = 0;
+ }
v->arch.arch_vmx.vmcs = 0;
free_monitor_pagetable(v);
else
addr = regs->edx & 0xffff;
- if (addr == 0x80) {
- __update_guest_eip(inst_len);
- return;
- }
-
vio = get_vio(d->domain, d->vcpu_id);
if (vio == 0) {
printk("bad shared page: %lx", (unsigned long) vio);
free_xenheap_pages(vmcs, order);
}
-static inline int construct_vmcs_controls(void)
+static inline int construct_vmcs_controls(struct arch_vmx_struct *arch_vmx)
{
int error = 0;
+ void *io_bitmap_a;
+ void *io_bitmap_b;
error |= __vmwrite(PIN_BASED_VM_EXEC_CONTROL,
MONITOR_PIN_BASED_EXEC_CONTROLS);
error |= __vmwrite(VM_ENTRY_CONTROLS, MONITOR_VM_ENTRY_CONTROLS);
+ /* need to use 0x1000 instead of PAGE_SIZE */
+ io_bitmap_a = (void*) alloc_xenheap_pages(get_order(0x1000));
+ io_bitmap_b = (void*) alloc_xenheap_pages(get_order(0x1000));
+ memset(io_bitmap_a, 0xff, 0x1000);
+ /* don't bother debug port access */
+ clear_bit(PC_DEBUG_PORT, io_bitmap_a);
+ memset(io_bitmap_b, 0xff, 0x1000);
+
+ error |= __vmwrite(IO_BITMAP_A, (u64) virt_to_phys(io_bitmap_a));
+ error |= __vmwrite(IO_BITMAP_B, (u64) virt_to_phys(io_bitmap_b));
+
+ arch_vmx->io_bitmap_a = io_bitmap_a;
+ arch_vmx->io_bitmap_b = io_bitmap_b;
+
return error;
}
(unsigned long) vmcs_phys_ptr);
return -EINVAL;
}
- if ((error = construct_vmcs_controls())) {
+ if ((error = construct_vmcs_controls(arch_vmx))) {
printk("construct_vmcs: construct_vmcs_controls failed\n");
return -EINVAL;
}
CPU_BASED_INVDPG_EXITING | \
CPU_BASED_MWAIT_EXITING | \
CPU_BASED_MOV_DR_EXITING | \
+ CPU_BASED_ACTIVATE_IO_BITMAP | \
CPU_BASED_UNCOND_IO_EXITING \
)
unsigned long shadow_gs;
};
+#define PC_DEBUG_PORT 0x80
+
struct arch_vmx_struct {
struct vmcs_struct *vmcs; /* VMCS pointer in virtual */
unsigned long flags; /* VMCS flags */
unsigned long cpu_cr3;
unsigned long cpu_state;
struct msr_state msr_content;
+ void *io_bitmap_a, *io_bitmap_b;
};
#define vmx_schedule_tail(next) \